package org.gokeep.communication.engine.udp;

import lombok.extern.slf4j.Slf4j;
import org.gokeep.common.exception.GoKeepException;
import org.springframework.stereotype.Component;

import java.net.DatagramPacket;

/**
 * @author xuning
 */
@Slf4j
@Component
public class UdpClient {
    private static final String DEFAULT_LISTEN_QUEUE_THREAD_NAME = "UDP_CLIENT_QUEUE_LISTEN_THREAD";

    private UdpClientQueueLister udpClientQueueLister;

    private InetAddress address;


    /**
     * 无参构建
     */
    public UdpClient() {

    }

    /**
     * 根据地址构造
     *
     * @param address
     */
    public UdpClient(InetAddress address) {
        this(address, null);
    }

    /**
     * 根据地址构造
     *
     * @param host
     * @param port
     */
    public UdpClient(String host, int port) {
        this(host, port, null);
    }

    /**
     * 根据地址和udp监听器构造
     *
     * @param address
     * @param udpClientQueueLister
     */
    public UdpClient(InetAddress address, UdpClientQueueLister udpClientQueueLister) {
        this.address = address;
        this.udpClientQueueLister = udpClientQueueLister;
    }

    /**
     * 根据地址和udp监听器构造
     *
     * @param host
     * @param port
     * @param udpClientQueueLister
     */
    public UdpClient(String host, int port, UdpClientQueueLister udpClientQueueLister) {
        this(InetAddress.build(host, port), udpClientQueueLister);
    }


    /**
     * 设置发送监听器构建
     *
     * @param udpClientQueueLister
     */
    public UdpClient(UdpClientQueueLister udpClientQueueLister) {
        this(null, udpClientQueueLister);
    }

    /**
     * 构建地址
     *
     * @param address
     * @return
     */
    public UdpClient buildAddress(InetAddress address) {
        this.address = address;
        return this;
    }

    /**
     * 添加监听器构建
     *
     * @param udpClientQueueLister
     * @return
     */
    public UdpClient buildListenQueue(UdpClientQueueLister udpClientQueueLister) {
        this.udpClientQueueLister = udpClientQueueLister;
        return this;
    }

    /**
     * 智能获取地址信息
     *
     * @return
     */
    private InetAddress smartGetAddress(Message message) {
        if (message.getAddress() != null) {
            return message.getAddress();
        }
        if (null != this.address) {
            return this.address;
        }
        throw new GoKeepException("Udp address is null");
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public void send(Message message) {
        DatagramPacket datagramPacket = new DatagramPacket(
                message.getPayload(),
                message.getPayload().length,
                smartGetAddress(message).socketAddress()
        );
        this.udpClientQueueLister.add(datagramPacket);
    }


    /**
     * 停止客户端监听队列
     */
    public void stop() {
        this.udpClientQueueLister.stop();
    }

    /**
     * 开始发送队列监听器
     */
    public void startUdpClientMessageLister() {
        startUdpClientMessageLister(DEFAULT_LISTEN_QUEUE_THREAD_NAME);
    }

    /**
     * 构建客户端监听
     */
    public void startUdpClientMessageLister(String listerName) {
        if (this.udpClientQueueLister == null) {
            this.udpClientQueueLister = new UdpClientQueueLister();
        }
        Thread multicastListerThread = new Thread(udpClientQueueLister);
        multicastListerThread.setDaemon(false);
        multicastListerThread.setName(listerName);
        multicastListerThread.start();
        log.info("Enable udp client listen queue thread success, ThreadName: {}", listerName);
    }
}
